/**
 * WeaponEntity.java
 *
 *
 * $LastChangedBy:  $
 * $LastChangedDate:  $
 * $Revision:  $
 */
package com.game.dbpersistence.game.entity;

import com.game.dbpersistence.game.mapper.WeaponEntityMapper;
import com.game.message.proto.weapon.WeaponProtoBuf.WeaponInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.game.core.db.common.annotation.DbMapper;
import com.game.core.db.common.annotation.FieldSave;
import com.game.core.db.common.annotation.MethodSaveProxy;
import com.game.core.db.entity.BaseStringIDEntity;
import com.game.core.db.service.redis.RedisKeyEnum;
import com.game.core.db.service.redis.RedisListInterface;
import java.io.IOException;
import java.lang.ClassNotFoundException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Domain object class for WeaponEntity
 *
 * @author CodeMaster v1.0
 */
@DbMapper(mapper = WeaponEntityMapper.class)
public class WeaponEntity extends BaseStringIDEntity implements RedisListInterface, Cloneable {
	final static Logger logger = LoggerFactory.getLogger(WeaponEntity.class);
	/**
	 * 默认生成的账号实体的ID，每次创建自动加 1 *
	 */
	@FieldSave
	private long id;
	/**
	 * 创建唯一关键字索引UUID *
	 */
	@FieldSave
	private String uid;
	/**
	 * 该实体是否在过有效期后需要需要自动从缓存中删除 *
	 */
	@FieldSave
	private boolean deleted;
	/**
	 *  设置有效期时间，默认从当前创建时间加24小时合86400秒 *
	 */
	@FieldSave
	private Date deleteTime;
	/**
	 * 武器装备所属的玩家的UID *
	 */
	@FieldSave
	private String ownerId;
	/**
	 * 武器装备的ID *
	 */
	@FieldSave
	private int weaponId;
	/**
	 * 武器装备的名称 *
	 */
	@FieldSave
	private String name; 
	/**
	 * 类别（1刀剑2枪3锤4盾5弓6匕首） *
	 */
	@FieldSave
	private int weaponType = 0;
	/**
	 * 档位（1.简单；2.普通；3.困难；4.噩梦；5.遗迹） *
	 */
	@FieldSave
	private int weaponLevel = 0;
	/**
	 * 该武器强化的最大等级  *
	 */
//	@FieldSave
//	private int weaponMaxLevel = 0;
	/**
	 * 主动技能  *
	 */
	@FieldSave
	private int mainSkillId = 0;
	/**
	* 武器装备的品质 *
	*/
//	@FieldSave
//	private int quality;
	/**
	* 武器装备已解锁的天赋列表 中间用 "|" 分隔*
	*/
	@FieldSave
	private String talents;
	/**
	 * 武器装备强化附加装备ID *
	 */
	@FieldSave
	private String combines;

	/**
	 * 武器装备强化主线节点 列表*
	 */
	@FieldSave
	private String mainNodes;

	/**
	 * 武器装备强化主线节点列表 *
	 */
	private  List<MainNode> mainNodeList;


	public WeaponEntity() {
		init();
	}
	
	public WeaponEntity(long id) {
		this.id = id;
		init();
	}
	
	public WeaponEntity(String uid) {
		this.uid = uid;
		init();
	}
	/** Gets */
	@Override
	public long getId() {
		return this.id;
	}

	/** Gets */
	@Override
	public String getUid() {
		return this.uid;
	}

	/** Gets */
	@Override
	public boolean isDeleted() {
		return this.deleted;
	}

	/** Gets */
	@Override
	public Date getDeleteTime() {
		return this.deleteTime;
	}

	/** Gets */
	public String getOwnerId() {
		return this.ownerId;
	}

	/** Gets */
	public int getWeaponId() {
		return this.weaponId;
	}

	/** Gets */
	public String getName() {
		return this.name;
	}
	
	/** Gets */
	public int getWeaponType() {
		return this.weaponType;
	}

	/** Gets */
	public int getWeaponLevel() {
		return this.weaponLevel;
	}

	/** Gets */
//	public int getWeaponMaxLevel() {
//		return this.weaponMaxLevel;
//	}
	
	/** Gets */
	public int getMainSkillId() {
		return this.mainSkillId;
	}
	
	/** Gets */
	public String getTalents() {
		if((this.talents.isEmpty())&&(this.mainNodeList != null)&&(this.mainNodeList.size()>0)){
			this.talents = getMainNodeListTalents(this.mainNodeList);
		}
		return this.talents;
	}

	/** Gets */
	public String getCombines() {
		return this.combines;
	}

	/** Gets */
	public String getMainNodes() {
		if((this.mainNodes.isEmpty())&&(this.mainNodeList != null)&&(this.mainNodeList.size()>0)){
			this.mainNodes = JSON.toJSONString(this.mainNodeList);
		}
		return this.mainNodes;
	}
	
	/** Gets */
	public int getMainNodeCostCoin(int mainId){
		for(MainNode mainNode : mainNodeList) {
			if (mainNode.getId() == mainId) {
				return mainNode.getCost();
			}
		}
		return -1;
	}
	
	/** Gets */
	public int getItemNodeCostCoin(int mainId,int itemId){
		for(MainNode mainNode : mainNodeList) {
			if (mainNode.getId() == mainId) {
				List<ItemNode> itemNodeList = mainNode.getItemNodeList();
				if((mainNode.getStatus()==1)&&(itemNodeList!=null)&&(itemNodeList.size()>0)) {
					for(ItemNode itemNode : itemNodeList) {
						if(itemNode.getId() == itemId) {
							return itemNode.getCost();
						}
					}
				}
			}
		}
		return -1;
	}
	
	/** Gets */
	@SuppressWarnings("unchecked")
	public List<MainNode> getMainNodeList() {
		if((this.mainNodeList.size() == 0)&&(!this.mainNodes.isEmpty())) {
			List<JSONObject> jsonObjects = JSON.parseObject(this.mainNodes, List.class);
			if ((jsonObjects != null) && (jsonObjects.size() > 0)) {
				this.mainNodeList.clear();
				for (JSONObject jsonObject : jsonObjects) {
					MainNode mainNode = JSON.toJavaObject(jsonObject, MainNode.class);
					if(mainNode!=null) {
						this.mainNodeList.add(mainNode);
					}
				}
			}
		}
		return this.mainNodeList;
	}
	
	/** Gets */
	public String getMainNodeListTalents(List<MainNode> mainNodeList) {
		String talents = "";
		for(MainNode mainNode : mainNodeList) {
			List<ItemNode> itemNodeList = mainNode.getItemNodeList();
			if((mainNode.getStatus()==1)&&(itemNodeList!=null)&&(itemNodeList.size()>0)) {
				for(ItemNode itemNode : itemNodeList) {
					if((itemNode.getStatus()==1)&&(itemNode.getTalent() != 0)) {
						talents = talents + itemNode.getTalent() + "|";
					}
				}
			}
		}
		if(talents.length()>0) {
			talents = talents.substring(0, talents.length()-1);
		}
		return talents;
	}
	
	/** Initializes the values */
	public void init() {
		if (this.id == 0) {
			this.id = super.getId();
		}
		if (this.uid == null || this.uid == "") {
			this.uid = super.getUid();
		}
		this.deleted = false;
		this.deleteTime = new Date();
		this.ownerId = "";
		this.weaponId = 0;
		this.name = "";
		this.weaponType = 0;
		this.weaponLevel = 0;
		//this.weaponMaxLevel = 0;
		this.mainSkillId = 0 ;
		this.talents = "";
		this.combines = "";
		this.mainNodes = "";
		this.mainNodeList = new ArrayList<MainNode>();
	}

	/** Sets */
	@Override
	@MethodSaveProxy(proxy = "id")
	public void setId(long id) {
		this.id = id;
	}

	/** Sets */
	@Override
	@MethodSaveProxy(proxy = "uid")
	public void setUid(String uid) {
		this.uid = uid;
	}

	/** Sets */
	@Override
	@MethodSaveProxy(proxy = "deleted")
	public void setDeleted(boolean deleted) {
		this.deleted = deleted;
	}

	/** Sets */
	@Override
	@MethodSaveProxy(proxy = "deleteTime")
	public void setDeleteTime(Date deleteTime) {
		this.deleteTime = deleteTime;
	}

	/** Sets */
	@MethodSaveProxy(proxy = "ownerId")
	public void setOwnerId(String ownerId) {
		this.ownerId = ownerId;
	}

	/** Sets */
	@MethodSaveProxy(proxy = "weaponId")
	public void setWeaponId(int weaponId) {
		this.weaponId = weaponId;
	}

	/** Sets */
	@MethodSaveProxy(proxy = "name")
	public void setName(String name) {
		this.name = name;
	}
	
	/** Sets */
	@MethodSaveProxy(proxy = "weaponType")
	public void setWeaponType(int weaponType) {
		this.weaponType = weaponType;
	}

	/** Sets */
	@MethodSaveProxy(proxy = "weaponLevel")
	public void setWeaponLevel(int weaponLevel) {
		this.weaponLevel = weaponLevel;
	}

	/** Sets */
//	@MethodSaveProxy(proxy = "weaponMaxLevel")
//	public void setWeaponMaxLevel(int weaponMaxLevel) {
//		this.weaponMaxLevel = weaponMaxLevel;
//	}

	/** Sets */
	@MethodSaveProxy(proxy = "mainSkillId")
	public void setMainSkillId(int mainSkillId) {
		this.mainSkillId = mainSkillId;
	}
	
	/** Sets */
	@MethodSaveProxy(proxy = "talents")	
	public void setTalents(String talents) {
		if((talents != null)&&(!talents.isEmpty())){
			this.talents = talents;
		}
	}
	
	/** Sets */
	@MethodSaveProxy(proxy = "combines")
	public void setCombines(String combines) {
		this.combines = combines;
	}

	/** Sets */
	@MethodSaveProxy(proxy = "mainNodes")
	public void setMainNodes(String mainNodes) {
		if((mainNodes != null)&&(!mainNodes.isEmpty())){
			this.mainNodes = mainNodes;
		}
	}

	/** Sets */
	public void setMainNodeList(List<MainNode> mainNodeList) {
		if((mainNodeList != null)&&(mainNodeList.size()>0)){
			this.mainNodeList = mainNodeList;
			this.mainNodes = JSON.toJSONString(mainNodeList);
			this.talents = getMainNodeListTalents(mainNodeList);
		}
	}

	/** Sets */
	public int changeMainNodeStatus(int mainId, int status) {
		//此处替换需要测试
		this.getMainNodeList();
		if((this.mainNodeList != null)&&(this.mainNodeList.size()>0)){
			for(int index=0; index < this.mainNodeList.size(); index++){
				MainNode mainNode = (MainNode)(this.mainNodeList.get(index));
				if(mainNode.getId() == mainId) {
					if(mainNode.getStatus() != 1) {
						MainNode preMainNode = (MainNode)(this.mainNodeList.get(index-1));
						if((preMainNode != null)&&(preMainNode.getStatus() == 1)) {
							mainNode.setStatus(status);
							this.mainNodes = "";
							this.talents = "";
							return 1;//条件满足，解锁成功，返回 1
						}else {
							return 2;//解锁前置条件不满足，解锁失败，返回 2
						}
					}else {
						return 0;//该节点已经解锁，解锁失败，返回 0
					}
				}
			}
		}
		return -1;//节点不存在，解锁失败， 返回 -1
	}
	
	/** Sets */
	public int changeItemNodeStatus(int mainId, int itemId, int status) {
		this.getMainNodeList();
		if((this.mainNodeList != null)&&(this.mainNodeList.size()>0)){
			for(MainNode mainNode : this.mainNodeList) {
				if(mainNode.getId() == mainId) {
					if(mainNode.getStatus() == 1) {
						List<ItemNode> itemNodeList = mainNode.getItemNodeList();
						for(ItemNode itemNode : itemNodeList) {
							if(itemNode.getId() == itemId) {
								if(itemNode.getStatus() != 1) {
									itemNode.setStatus(status);
									this.mainNodes = "";
									this.talents = "";
									return 1;//条件满足，解锁成功，返回 1
								}else {
									return 0;//该节点已经解锁，解锁失败，返回 0
								}
							}
						}
					}else {
						return 2;//解锁前置条件不满足，解锁失败，返回 2
					}
				}
			}
		}
		return -1;//节点不存在，解锁失败， 返回 -1
	}
	
	/** depth clone **/
	public Object clone() {
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(this);
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bis);
			return ois.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	/** Returns the String representation */
	public String toString() {
		return "(WeaponEntity) "
				+ "id='" + id + "', "
				+ "uid='" + uid + "', "
				+ "ownerId='" + ownerId + "', "
				+ "weaponId='" + weaponId + "', "
				+ "name='" + name + "', "
				+ "weaponType='" + weaponType + "', "
				+ "weaponLevel='" + weaponLevel + "', "
				//+ "weaponMaxLevel='" + weaponMaxLevel + "', "
				+ "mainSkillId='" + mainSkillId + "', "
				+ "talents='" + talents + "', "
				+ "combines='" + combines + "', "
				+ "mainNodes='" + mainNodes + "'";
	}

	/** Returns the CSV String */
	public String toCSVLine() {
		return "\""
				+ id + "\"," + "\""
				+ uid + "\"," + "\""
				+ ownerId + "\"," + "\""
				+ weaponId + "\"," + "\""
				+ name + "\"," + "\""
				+ weaponType + "\"," + "\""
				+ weaponLevel + "\"," + "\""
				//+ weaponMaxLevel + "\"," + "\""
				+ mainSkillId + "\"," + "\""
				+ talents + "\"," + "\""
				+ combines + "\"," + "\""
				+ mainNodes + "\"";
	}

	@Override
	public String getShardingKey() {
		return getOwnerId();
	}

	@Override
	public String getSubUniqueKey() {
		return String.valueOf(getWeaponId());
	}

	@Override
	public String getRedisKeyEnumString() {
		return RedisKeyEnum.WEAPON.getKey();
	}

	/**
	 * Returns the proto value of the object
	 * @return
	 */
	public WeaponInfo.Builder toProto () {
		WeaponInfo.Builder builderInfo = WeaponInfo.newBuilder();
		builderInfo.setUid(this.getUid());
		builderInfo.setWeaponId(this.getWeaponId());
		builderInfo.setName(this.getName());
		builderInfo.setWeaponType(this.getWeaponType());
		builderInfo.setWeaponLevel(this.getWeaponLevel());
		//builderInfo.setWeaponMaxLevel(this.getWeaponMaxLevel());
		builderInfo.setMainSkillId(this.getMainSkillId());
		builderInfo.setTalents(this.getTalents());
		builderInfo.setCombines(this.getCombines());
		builderInfo.setForged(this.getCombines());
		//builderInfo.addAllMainNodeList(this.mainNodeList);
		this.getMainNodeList();
		if ((this.mainNodeList != null) && (this.mainNodeList.size() > 0)) {
			try {
				for (MainNode mainNode : this.mainNodeList) {
					builderInfo.addMainNodeList(mainNode.toProto());
				}
			} catch (Exception e) {
				logger.error(e.toString());
			}
		}
		return builderInfo;
	}

}
